DEFINT A-Z

TYPE BMPHeaderT
    id AS STRING * 2
    size AS LONG
    rr1 AS INTEGER
    rr2 AS INTEGER
    offset AS LONG
    hsize AS LONG
    wid AS LONG
    hei AS LONG
    planes AS INTEGER
    bpp AS INTEGER
    pakbyte AS LONG
    imagebytes AS LONG
    xres AS LONG
    yres AS LONG
    colch AS LONG
    ic AS LONG
END TYPE

DIM SHARED DPAL(15,2) AS INTEGER
DIM SHARED BF(11,2000) AS INTEGER,RLE(500) AS INTEGER
DIM SHARED DF(5000) AS INTEGER,DFC(4000) AS INTEGER
DIM SHARED MUS(80) AS STRING
COMMON SHARED RLEL AS INTEGER,DFL AS INTEGER,MUSL AS INTEGER

FOR I=0 TO 15:READ DPAL(I,0),DPAL(I,1),DPAL(I,2):NEXT I
DATA &H00,&H00,&H00, &H00,&H00,&Ha8, &H00,&Ha8,&H00, &H00,&Ha8,&Ha8
DATA &Ha8,&H00,&H00, &Ha8,&H00,&Ha8, &Ha8,&Ha8,&H00, &Ha8,&Ha8,&Ha8
DATA &H54,&H54,&H54, &H54,&H54,&Hff, &H54,&Hff,&H54, &H54,&Hff,&Hff
DATA &Hff,&H54,&H54, &Hff,&H54,&Hff, &Hff,&Hff,&H54, &Hff,&Hff,&Hff

FOR I=0 TO 11
  F$=LTRIM$(RTRIM$(STR$(I))):IF I<10 THEN F$="0"+F$
  CALL LOADBMP(F$+".BMP",BF(),I)
NEXT I

CALL ARRCPY(DF(),BF(),0,2000)
RLEL=0:CALL GETRLE(RLE(),RLEL,DF(),2000)
DFL=0:FOR I=0 TO 10:CALL IMGDIFF(DF(),DFL,BF(),I,I+1):NEXT I
CALL IMGDIFF(DF(),DFL,BF(),11,0)
DFCL=0:CALL GETRLE(DFC(),DFCL,DF(),DFL)

NOTES$="GGAAD#EEDD#DCCCCDDD#D#D#DCDEGAEGDECDCEEGGAEGDECD#ED#DCDD#D#CDEGD#EDCDDCCDDGGAAD#EEDD#DCCCCDDD#D#D#DCDEGAEGDECDCEEGGAEGDECD#ED#DCDD#D#CDEGD#EDCDDCCCCCC<GA>CC<GA>CDECFEFGCCCC<GA>C<G>FEDC<FEFG>CC<GA>CC<GA>CCDEC<GAG>CCC<B>C<GA>CFEFGCC<BB>CC<GA>CC<GA>CDECFEFGCCCC<GA>C<G>FEDC<FEFG>CC<GA>CC<GA>CCDEC<GAG>CCC<B>C<GA>CFEFGCCDD"
MUSL=0:CALL SplitNotes(MUS(),MUSL,NOTES$,4)

OPEN "NYANCAT.TXT" FOR OUTPUT AS #1
CALL SAVEARRSTR(MUS(),MUSL,10)
CALL SAVEARR(DFC(),DFCL,22)
CALL SAVEARR(RLE(),RLEL,22)
CLOSE #1
END

SUB ARRCPY(D() AS INTEGER,S() AS INTEGER,IDX AS INTEGER,L AS INTEGER)
  STATIC I AS INTEGER
  FOR I=0 TO L-1:D(I)=S(IDX,I):NEXT I
END SUB

SUB LOADBMP(FBMP AS STRING,BUF() AS INTEGER,IDX AS INTEGER)
  STATIC hdr AS BMPHeaderT,PAL AS STRING*64,LN AS STRING*80
  STATIC I AS INTEGER,Y AS INTEGER,P AS INTEGER
  STATIC A AS INTEGER,B AS INTEGER,A1,B1
  DIM COLTAB(15) AS INTEGER

  OPEN FBMP FOR BINARY AS #1
  GET #1,1,hdr
  IF "BM"<>hdr.id THEN PRINT "Invalid BMP File.":END
  W=hdr.wid: H=hdr.hei
  IF W<>80 OR H<>50 OR hdr.bpp<>4 THEN PRINT "Not 80x50x16 BMP file.":END
  rowBytesBmp=((W+31)\32)*4
  GET #1,15+hdr.hsize,PAL
  FOR I=0 TO 15
    B=ASC(MID$(PAL,I*4+1,1))
    G=ASC(MID$(PAL,I*4+2,1))
    R=ASC(MID$(PAL,I*4+3,1))
    COLTAB(I)=GETCOLOR(R,G,B)
  NEXT I
  P=0
  FOR Y=0 TO 24
    GET #1,15+hdr.hsize+64+(24-Y)*80,LN
    FOR I=1 TO 40
      A=ASC(MID$(LN,I+40,1)):B=ASC(MID$(LN,I,1))
      A1=COLTAB(A\16):B1=COLTAB(B\16)
      BUF(IDX,P)=(A1*16) OR B1:P=P+1
      A1=COLTAB(A AND 15):B1=COLTAB(B AND 15)
      BUF(IDX,P)=(A1*16) OR B1:P=P+1
    NEXT I
  NEXT Y
  CLOSE #1
END SUB

FUNCTION GETCOLOR(R AS INTEGER,G AS INTEGER,B AS INTEGER)
  STATIC I AS INTEGER,D AS LONG,DMIN AS LONG,RS AS INTEGER
  DMIN=-1:RS=0
  FOR I=0 TO 15
    D=(R-DPAL(I,0))^2 + (G-DPAL(I,1))^2 + (B-DPAL(I,2))^2
    IF DMIN=-1 OR D<DMIN THEN DMIN=D:RS=I
  NEXT I
  GETCOLOR=RS
END FUNCTION

SUB SplitNotes(D() AS STRING,L AS INTEGER,NOTES AS STRING,BSZ AS INTEGER)
  STATIC BLK AS STRING,I AS INTEGER
  BLK="":FOR I=1 TO LEN(NOTES)
    C$=MID$(NOTES,I,1)
    IF C$<>" " THEN
      IF C$<>"#" AND LEN(BLK)>=BSZ THEN
        D(L)=BLK:L=L+1:BLK=""
      END IF
      BLK=BLK+C$
    END IF
  NEXT I
  IF BLK<>"" THEN D(L)=BLK:L=L+1
END SUB

SUB GETRLE(D() AS INTEGER,L AS INTEGER,S() AS INTEGER,SLEN AS INTEGER)
  STATIC I,I0,J,RP,CUR
  I=0:WHILE I<SLEN
    CUR=S(I):RP=1:J=I+1
    WHILE J>0 AND J<SLEN AND RP<127
      IF S(J)=CUR THEN J=J+1:RP=RP+1 ELSE J=0
    WEND
    IF RP>=3 THEN
      D(L)=RP OR 128:D(L+1)=CUR:L=L+2:I=I+RP
    ELSE
      I0=I:I=I+RP:J=0
      WHILE I<SLEN AND I-I0<127 AND J=0
        CUR=S(I):RP=1:J=I+1
        WHILE J>0 AND J<SLEN AND J<I+3
          IF S(J)=CUR THEN J=J+1 ELSE J=0
        WEND
	IF J=0 THEN I=I+1
      WEND
      D(L)=I-I0:L=L+1:FOR J=I0 TO I-1:D(L)=S(J):L=L+1:NEXT J
    END IF
  WEND
  D(L)=128:L=L+1
END SUB

SUB IMGDIFF(D() AS INTEGER,DI AS INTEGER,S() AS INTEGER,I0 AS INTEGER,I1 AS INTEGER)
  STATIC Y,L,I
  DIM LD(160) AS INTEGER
  FOR Y=0 TO 24
    CALL LINEDIFF(LD(),L,S(),I0,I1,Y)
    IF L>0 THEN
      D(DI)=Y OR &HE0:DI=DI+1
      FOR I=0 TO L-1:D(DI)=LD(I):DI=DI+1:NEXT I
    END IF
  NEXT Y
  D(DI)=255:DI=DI+1
END SUB

SUB LINEDIFF(R() AS INTEGER,L AS INTEGER,S() AS INTEGER,I0 AS INTEGER,I1 AS INTEGER,Y AS INTEGER)
  STATIC X0,X,CNT,I,OF
  DIM G(80) AS INTEGER
  L=0:X0=-1:CNT=0
  FOR X=0 TO 79
    OF=Y*80+X
    IF S(I0,OF)<>S(I1,OF) THEN
      IF CNT=0 THEN X0=X
      G(CNT)=S(I1,OF)
      CNT=CNT+1
    ELSEIF CNT>0 THEN
      R(L)=X0:R(L+1)=CNT:L=L+2
      FOR I=0 TO CNT-1:R(L)=G(I):L=L+1:NEXT I
      CNT=0
    END IF
  NEXT X
  IF CNT>0 THEN
    R(L)=X0:R(L+1)=CNT:L=L+2
    FOR I=0 TO CNT-1:R(L)=G(I):L=L+1:NEXT I
  END IF
END SUB

SUB SAVEARR(A() AS INTEGER,L AS INTEGER,CL AS INTEGER)
  PRINT #1,"DATA ";
  FOR I=0 TO L-1
    PRINT #1,LTRIM$(RTRIM$(STR$(A(I))));
    IF I>=L-1 THEN
       PRINT #1,""
    ELSEIF ((I+1) MOD CL)=0 THEN
       PRINT #1,"":PRINT #1,"DATA ";
    ELSE
       PRINT #1,",";
    END IF
  NEXT I
END SUB

SUB SAVEARRSTR(A() AS STRING,L AS INTEGER,CL AS INTEGER)
  PRINT #1,"DATA ";L
  PRINT #1,"DATA ";
  FOR I=0 TO L-1
    PRINT #1,CHR$(34);A(I);CHR$(34);
    IF I>=L-1 THEN
       PRINT #1,""
    ELSEIF ((I+1) MOD CL)=0 THEN
       PRINT #1,"":PRINT #1,"DATA ";
    ELSE
       PRINT #1,",";
    END IF
  NEXT I
END SUB

